home *** CD-ROM | disk | FTP | other *** search
/ JCSM Shareware Collection 1993 November / JCSM Shareware Collection - 1993-11.iso / cl720 / vxbase1j.lzh / README.TXT < prev    next >
Text File  |  1993-06-18  |  58KB  |  1,573 lines

  1. vxBase 3.02  June 18, 993
  2. -------------------------
  3. This is a new major release of vxBase numbered 3.0X. It contains a new set of
  4. functions designed to store, manage, and retrieve bitmaps. It also contains
  5. a set of functions that will create and maintain permanent subindexes - plus
  6. MORE. In all, 18 new functions have been added.
  7.  
  8. Changes to version vxBase 2.xx are documented after the new function
  9. writeups.
  10.  
  11. NOTE: Release 3.02 adds function vxLockRetry which allows much greater
  12.       flexibility in locking protocol and error reporting. See below.
  13.  
  14.  
  15.  
  16. BITMAPS
  17. -------
  18. The bitmaps are stored in standard xBase memo files. Fields in the dbf which
  19. contain block references to the bitmaps are standard type "M" fields. An
  20. attempt to display the bitmap using third party xBase software (e.g., Clipper
  21. or even the current release of DataWorks) will show "BIT*MAP". If these
  22. memos are replaced with text, the bitmaps will be lost.
  23.  
  24. An updated vxbtest project is included in the zip. To show off the bitmap
  25. functions, run it and select "Link" and then "Show Pictures" from the
  26. main menu. The code that shows the bitmaps is in VYFORM2. If you are running
  27. the sample on a low resolution monitor (i.e., 640x480), maximize 
  28. the form. You should also make the vxCtlBrowse box a little wider and
  29. deeper. 
  30.  
  31. Collecting Bitmaps
  32. ------------------
  33. Images stored in a vxBase memo file are most easily transferred via
  34. a bitmap file (files with .BMP extensions).
  35.  
  36. vxBase takes advantage of the rich body of functions included in Visual
  37. Basic to handle bitmap files. Bitmaps are the Windows norm; all paint
  38. programs, viewers, etc. can handle bitmaps - and most programs that
  39. deal with pictures can convert foreign formats (e.g., GIF) to BMPs.
  40. As a last resort, cut a picture into the clipboard and paste it into a 
  41. Windows PAINT window. It can then be stored as a .BMP file. 
  42.  
  43. Once an image is stored in a BMP file it can be transferred to the 
  44. memo file with the vxPictureImport function. To retrieve the bitmap,
  45. vxBase uses the standard Windows Clipboard. It puts the bitmap out to
  46. the clipboard as a DIB (device independent bitmap). The Visual Basic
  47. Clipboard.GetData(8) function then is used to retrieve the image
  48. from the clipboard and display it in a VB Picture Box. The box
  49. can have the AUTORESIZE property set to TRUE as in the sample
  50. application if the images are all different sizes
  51.  
  52. C programmers can store ANY KIND of BLOB (binary large object) in a memo 
  53. file with vxBlobWrite and retrieve the BLOBs with vxBlobRead. Contact the
  54. author for more information on these functions.
  55.  
  56.  
  57. SUBINDEXES
  58. ----------
  59. A subindex is an index that represents a defined subset of records in the
  60. main dbf file. The indexing expression is in no way related to the
  61. conditional expression that determines whether or not the record will be 
  62. represented in the index. In other words, the condition that determines
  63. the presence or absence of a key does not depend upon the value of the
  64. key. For example, a subindex may be created using the expression
  65. "upper(custname)" as the key. The conditional expression could be
  66. "(left(vxcountry,6)="CANADA") .or. (left(vxcountry,6)="U.S.A.". This
  67. would produce an index that represented customers in North America only.
  68. An open subindex in an index list attached to a database is maintained
  69. just as like other index. When a record is added, an index key for the
  70. record is only added if the conditional expression evaluates as TRUE.
  71. If a record is updated, and the update data invalidates the record
  72. for inclusion in the subindex, the key is deleted.
  73.  
  74. If you regularly filter data based upon a condition such as the one
  75. above, a permanent subindex makes data retrieval MUCH faster. If the
  76. file is large, and you need to set a temporary filter that may result
  77. in very long record retrieval times, it is probably faster to create
  78. a temporary subindex instead. A subindex makes it APPEAR that the database
  79. contains only records that satisfy the conditional logical expression.
  80.  
  81.  
  82. COMPATIBILITY ISSUES
  83. --------------------
  84. With release 3.0X, vxBase breaks away from strict xBase standards. Bitmaps
  85. of course may only be retrieved and displayed using vxBase functions.
  86. The header block of a subindex also differs from a standard Clipper NTX
  87. index header block. New elements have been added that define whether or
  88. not the index is a subindex and an area is used to hold the conditional
  89. expression as well. 
  90.  
  91. Release 5.2 of CA-Clipper changes the index header as well and also changes
  92. the index locking scheme. vxBase NTX indexes ARE NOT COMPATIBLE with Clipper
  93. 5.2 indexes. Indexes created and/or maintained with any version of Clipper
  94. will NOT properly maintain a vxBase subindex.
  95.  
  96. Bitmaps and subindexes are specialty items requested by a great many vxBase
  97. users. If compatibility is an issue with your application, it would be best
  98. not to use these functions (although bitmaps may be safely ignored; if the
  99. memo text returns "BIT*MAP" then it may be ignored in a Clipper application).
  100.  
  101.  
  102. vxCtlBrowseMsg
  103. --------------
  104. A new message type has been created to extract the current contents of the
  105. user entered quick key value. Define the message in your global module as
  106.  
  107. Global Const VXB_QUICKDISPLAY = 12
  108.  
  109. A quick key entry will normally result in a the record pointer being
  110. moved so the KeyCode middle button down event generated by vxCtlBrowse
  111. whenever a new record is highlighted may be used to conveniently ask 
  112. for the current quick value. The new message may be used to display
  113. the current quick value in a text box as follows:
  114.  
  115. Sub BrowseBox_KeyDown (KeyCode As Integer, Shift As Integer)
  116. '   Debug.Print KeyCode
  117.    If KeyCode = 4 Then
  118.       QWinLong& = vxCtlHwnd(QuickBox) 
  119.       ' Note: vxCtlHwnd normally returns an integer but you
  120.       ' must explicitly cast its value as a long integer
  121.       ' in order to fulfill the vxCtlBrowseMsg parameter
  122.       ' requirements 
  123.       k& = vxCtlBrowseMsg(vxCtlHwnd(BrowseBox), VXB_QUICKDISPLAY, ByVal QWinLong&)
  124.    End If
  125. End Sub
  126.  
  127. Note: A VB label MAY NOT BE USED to display the quick value because a
  128. label is a "graphical object" and therefore does not have a window 
  129. handle.
  130.  
  131.  
  132.  
  133. NEW FUNCTIONS
  134. -------------
  135.  
  136. vxBlobRead
  137. ----------
  138. Declaration:
  139. HANDLE FAR PASCAL  vxBlobRead (memofieldname)
  140. char*  memofieldname;          /* name of memo field holding blob */ 
  141.  
  142. Purpose:
  143.    Read a binary large object (blob) from a memo file that was stored with
  144. vxBlobWrite.
  145.  
  146. Parameters:
  147.    memofieldname is either a string variable or a literal string that
  148. contains a valid memo field name from the currently selected database.
  149. MemoFieldName may be qualified with a valid alias name that points to
  150. any open database.
  151.  
  152. Returns:
  153.    A HANDLE to global memory allocated by vxBase. The memory contains
  154. the blob. It is the programmer's responsibility to release the memory
  155. with GlobalFree when he is done with it.
  156.  
  157. Usage:
  158.    Any binary object may be stored in a memo field with vxBlobWrite and
  159. a HANDLE to that object may be extracted with vxBlobRead. The vxPicture
  160. functions are limited to standard BMPs and variants thereof. 
  161.  
  162. Example:
  163.  
  164. /* ********************************************* */
  165. /* DrawBlob uses a GIF library to place an       */
  166. /* image into the window passed to the function  */
  167. /* The blob is retrieved from the memo fieldname */
  168. /* stored in the current record                  */
  169. /* ********************************************* */
  170. BOOL DrawBlob(HWND hwnd, char *fieldname)
  171. {
  172.    HANDLE     hPicBuffer;      // mem handle to blob
  173.    LPSTR      lpPicBuffer;     // string addr of blob
  174.  
  175.    // get the handle to the blob
  176.    // if NULL, return FALSE
  177.    // ---------------------------
  178.    hPicBuffer = vxBlobRead(fieldname);
  179.    if (!hPicBuffer)
  180.       return(FALSE);
  181.    
  182.    // convert the handle to a string address
  183.    // --------------------------------------
  184.    lpPicBuffer = GlobalLock(hPicBuffer);
  185.  
  186.    // Draw the image
  187.    // --------------
  188.    if (!GifConverter(hwnd, lpPicBuffer))
  189.       {
  190.       GlobalUnlock(hPicBuffer);
  191.       GlobalFree(hPicBuffer);
  192.       return(FALSE);
  193.       }
  194.  
  195.    // release the memory
  196.    // ------------------
  197.    GlobalUnlock(hPicBuffer);
  198.    GlobalFree(hPicBuffer);
  199.    return(TRUE);
  200. }
  201.  
  202. See Also:
  203.    vxBlobWrite, vxIsPicture, vxPictureImport, vxPictureRead, vxMemoClear
  204.  
  205.  
  206. vxBlobWrite
  207. -----------
  208. Declaration:
  209. int FAR PASCAL  vxBlobWrite (hGlobal, memofieldname)
  210. HANDLE hGlobal;           // global handle to mem storing blob        
  211. char*  memofieldname;     // name of memo field to put it in
  212.  
  213. Purpose:
  214.    Write a binary large object (blob) into a memo file.
  215.  
  216. Parameters:
  217.    hGlobal is a handle to a global memory object that stores a
  218. binary large object.
  219.  
  220.    MemoFieldName is either a string variable or a literal string that
  221. contains a valid memo field name from the currently selected database.
  222. MemoFieldName may be qualified with a valid alias name that points to
  223. any open database.
  224.  
  225. Returns:
  226.    TRUE if the operation was successful and FALSE if not.
  227.  
  228. Usage:
  229.    Any binary object may be stored in a memo field with vxBlobWrite and
  230. a HANDLE to that object may be extracted with vxBlobRead. The vxPicture
  231. functions are limited to standard BMPs and variants thereof. 
  232.    vxBase does not free the global memory after writing the blob. That
  233. is the programmer's responsibility.
  234.  
  235. Example:
  236.  
  237. /* ********************************************** */
  238. /* GetBlob stores a GIF image into a memo field   */
  239. /* The blob is retrieved from the filename passed */
  240. /* to this function                               */
  241. /* ********************************************** */
  242. BOOL GetBlob(char *filename, char *fieldname)
  243. {
  244.  
  245.    int        hFile;           // dos file handle
  246.    DWORD      dwLength;        // import file length
  247.    HANDLE     hPicBuffer;      // mem handle to blob
  248.    LPSTR      lpPicBuffer;     // string addr of blob
  249.  
  250.    //  verify existence of import file
  251.    // --------------------------------
  252.    hFile = myFileOpen(filename, 0);
  253.    if (hFile < 0)      // if error, return FALSE
  254.       return(FALSE);
  255.       
  256.  
  257.    // if zero length, set error
  258.    // -------------------------
  259.    dwLength = myFileLength(hFile);
  260.    if (!dwLength)
  261.       return(FALSE);
  262.  
  263.    // if unable to allocate memory, set error
  264.    // ---------------------------------------
  265.    if (NULL == (hPicBuffer = GlobalAlloc(GHND, (DWORD)dwLength)))
  266.       {
  267.       _lclose(hFile);
  268.       return(FALSE);
  269.       }
  270.  
  271.    // read image
  272.    // ----------
  273.    lpPicBuffer = GlobalLock(hPicBuffer);
  274.    _hread(hFile, lpPicBuffer, (DWORD) dwLength); // huge read
  275.    _lclose(hFile);
  276.  
  277.    // write image to memo file
  278.    // ------------------------
  279.    GlobalUnlock(hPicBuffer);
  280.    if (!vxBlobWrite(hPicBuffer, fieldname))
  281.       {
  282.       GlobalFree(hPicBuffer);
  283.       return(FALSE);
  284.       }
  285.  
  286.    GlobalFree(hPicBuffer);
  287.    return(TRUE);
  288. }
  289.  
  290. See Also:
  291.    vxBlobRead, vxIsPicture, vxPictureImport, vxPictureRead, vxMemoClear
  292.  
  293.  
  294. vxCreateSubNtx
  295. --------------
  296. Declaration:
  297.    Declare Function vxCreateSubNtx Lib "vxbase.dll" (ByVal NewNtxName
  298. As String, ByVal NtxExpr As String, ByVal ForCond As String) As Integer
  299.  
  300. Purpose:
  301.    Create a permanent subindex that represents a defined subset of
  302. records in the main dbf file. Only records that pass the test of
  303. the defined conditional logical expression are included in the index.
  304.  
  305. Parameters:
  306.    NewNtxName is the name of the new index file that is created. The
  307. parameter may be a literal string or a string variable. It may include
  308. a complete path name. If an extension is not specified, vxBase defaults
  309. it to ".ntx". An existing file with the same name is overwritten. File
  310. names must begin with a letter. The file name length is limited by DOS
  311. to 8 characters.
  312.  
  313.    NtxExpr is a valid xBase expression (which may be as simple as a 
  314. field name) that is passed as either a literal string or as a string
  315. variable. Maximum length of the expression is 255 characters.
  316.  
  317.    ForCond is a valid xBase expression that evaluates as a logical
  318. TRUE or FALSE. The index built by vxCreateSubNtx is composed of
  319. keys built from records that satisfy the ForCond expression. The ForCond
  320. expression may be passed as either a literal string or as a string
  321. variable. Maximum length of the expression is 255 characters.
  322.  
  323. Usage:
  324.    A subindex is an index that represents a defined subset of records in the
  325. main dbf file. The indexing expression is in no way related to the
  326. conditional expression that determines whether or not the record will be 
  327. represented in the index. In other words, the condition that determines
  328. the presence or absence of a key does not depend upon the value of the
  329. key. For example, a subindex may be created using the expression
  330. "upper(custname)" as the key. The conditional expression could be
  331. "(left(vxcountry,6)="CANADA") .or. (left(vxcountry,6)="U.S.A.". This
  332. would produce an index that represented customers in North America only.
  333. An open subindex in an index list attached to a database is maintained
  334. just as like other index. When a record is added, an index key for the
  335. record is only added if the conditional expression evaluates as TRUE.
  336. If a record is updated, and the update data invalidates the record
  337. for inclusion in the subindex, the key is deleted.
  338.  
  339.    If you regularly filter data based upon a condition such as the one
  340. above, a permanent subindex makes data retrieval MUCH faster. If the
  341. file is large, and you need to set a temporary filter that may result
  342. in very long record retrieval times, it is probably faster to create
  343. a temporary subindex instead. A subindex makes it APPEAR that the database
  344. contains only records that satisfy the conditional logical expression.
  345.  
  346.  
  347. Warning:
  348.    If you are editing a file that is being controlled by a subindex (i.e.,
  349. the index currently selected), field changes or additions that result in
  350. the for condition returning FALSE will leave the record pointer in an
  351. undefined state after the record is saved. If the record is an update,
  352. the key will be removed from the index. If the record is an addition,
  353. the key will not be added to the index. IT IS YOUR RESPONSIBILTY to
  354. position the record pointer to a valid record if this should occur.
  355.    There are a number of ways this can be accomplished. If you know
  356. the condition, you can test if the new data will qualify the record
  357. for inclusion in the index. Or you may simply seek for the record again
  358. after writing. If it does not exist, you can position the record
  359. pointer to someplace you have prepared to go to before you began the
  360. update routine. This is the strategy used below:
  361.  
  362. Example (Updating a subindexed file safely):
  363. --------------------------------------------
  364.  
  365. ' Validate data when save button is pressed
  366. ' -----------------------------------------
  367. Sub CustSave_Click ()
  368.    ' verify something in the field
  369.    ' -----------------------------
  370.    j% = vxSelectDbf(vxClientDbf)
  371.    SeekKey$ = CustCode.Text
  372.    If EmptyString(SeekKey$) Then
  373.       MsgBox "vxSer Field cannot be empty"
  374.       Exit Sub
  375.    End If
  376.  
  377.    ' reread the record
  378.    ' -----------------
  379.    j% = vxSeek(SeekKey$)
  380.    ThisRec& = vxRecNo()
  381.  
  382.    ' now get previous record in case
  383.    ' in a subindex situation the changes
  384.    ' the user makes removes this record
  385.    ' from the index. 
  386.    ' The subindex condition here is
  387.    ' vxCountry = 'CANADA' .or. vxCountry = 'U.S.A.'
  388.    ' If the user has changed the country to 
  389.    ' something else, this record will disappear
  390.    ' from the index when it is written so we
  391.    ' must plan on what to do of this happens.
  392.    ' ----------------------------------------------
  393.    j% = vxSkip(-1)
  394.    If vxBof() Then
  395.       j% = vxTop()
  396.    End If
  397.    PrevRec& = vxRecNo()
  398.  
  399.    ' put record pointer back to update
  400.    ' ---------------------------------
  401.    j% = vxGo(ThisRec&)
  402.  
  403.    ' Data passed. Put it away
  404.    ' ------------------------
  405.    j% = vxLockRecord()
  406.    Call vxReplString("vxcompany", (CustCompany.Text))
  407.    Call vxReplString("vxname", (CustName.Text))
  408.    Call vxReplString("vxaddress1", (CustAddress.Text))
  409.    Call vxReplString("vxaddress2", (CustAddress2.Text))
  410.    Call vxReplString("vxcity", (CustCity.Text))
  411.    Call vxReplString("vxstate", (CustState.Text))
  412.    Call vxReplString("vxcountry", (CustCountry.Text))
  413.    Call vxReplString("vxzip", (CustZip.Text))
  414.    Call vxReplString("vxphone", (CustPhBus.Text))
  415.    Call vxReplString("vxfax", (CustFax.Text))
  416.    j% = vxWrite()
  417.    j% = vxWriteHdr()
  418.    j% = vxUnlock()
  419.  
  420.    ' Update status box
  421.    ' -----------------
  422.    VXFORM1.StatBar.Text = "Record " + LTrim$(Str$(ThisRec&)) + " saved"
  423.  
  424.    ' Now see if the record still exists in this index.
  425.    ' If it doesnt exist, the country has been changed
  426.    ' so we will go to the Previous record we saved 
  427.    ' above and load the form data with that. Otherwise,
  428.    ' this record data will remain on the form.
  429.    ' -------------------------------------------------
  430.    If Not vxSeek(SeekKey$) Then
  431.       j% = vxGo(PrevRec&)
  432.       CustDataLoad
  433.    End If
  434.    
  435.    CustReturn = BROWSE_EDIT
  436.    RecChange = False
  437. End Sub
  438.  
  439. Example (Creating a subindex):
  440.   ' we open a subindex just as we do a normal index
  441.   ' UserFname$ contains the path and name of the subindex
  442.   If Not vxFile(UserFname$) Then
  443.      vxCl1Ntx = vxCreateSubNtx(UserFname$, "vxser", "left(vxcountry,6)='CANADA'
  444.  .or. left(vxcountry,6)='U.S.A.'")
  445.   Else
  446.      vxCl1Ntx = vxUseNtx(UserFname$)
  447.   End If
  448.  
  449. See Also:
  450.    vxCreateNtx, vxIsSubNtx, vxNtxSubExpr, vxNumRecsSub, vxUseNtx
  451.  
  452.  
  453. vxIsPicture
  454. -----------
  455. Declaration:
  456.    Declare Function vxIsPicture Lib "vxbase.dll" (ByVal MemoFieldName
  457. As String) As Integer
  458.  
  459. Purpose:
  460.    Determine whether a bitmap is attached to the defined memo field.
  461.  
  462. Parameters:
  463.    MemoFieldName is either a string variable or a literal string that
  464. contains a valid memo field name from the currently selected database.
  465. MemoFieldName may be qualified with a valid alias name that points to
  466. any open database.
  467.  
  468. Returns:
  469.   TRUE if a bitmap is present and FALSE if not. Note that text attached
  470. to the field instead of a bitmap will return FALSE.
  471.  
  472. Usage:
  473.    Could be used to determine whether or not to load a new bitmap.
  474.  
  475. Example:
  476.  
  477.    ' the name of the bmp picture file is the
  478.    ' same as the string in field "title" so
  479.    ' we can import the bmps into the memo file
  480.    ' by cocatenating ".bmp" to the trimmed field
  481.    ' contents
  482.    ' -------------------------------------------
  483.    j% = vxTop()
  484.    If Not vxIsPicture("pic") Then
  485.       For i& = 1 To 13 ' there are 13 recs in the file
  486.          j% = vxGo(i&)
  487.          ftitle$ = vxFieldTrim("type")
  488.          fname$ = "c:\magic\bmp\" + ftitle$ + ".bmp"
  489.          If Not vxPictureImport(fname$, "pic") Then
  490.             MsgBox "Import Failed"
  491.          End If
  492.       Next i&
  493.       j% = vxClose() ' close ensures buffers flushed
  494.       AirPicsDbf = vxUseDbf("\vb\vxbtest\airpics.dbf")
  495.       j% = vxSelectDbf(AirPicsDbf)
  496.    End If  
  497.  
  498. See Also:
  499.    vxIsMemo, vxMemoClear, vxPictureImport, vxPictureRead, vxSetAlias
  500.  
  501.  
  502. vxIsSubNtx
  503. ----------
  504. Declaration:
  505.    Declare Function vxIsSubIndex Lib "vxbase.dll" (ByVal NtxArea As Integer)
  506. As Integer
  507.  
  508. Purpose:
  509.    Determine whether or not the defined index is a subindex or a normal
  510. index.
  511.  
  512. Parameters:
  513.    NtxArea is the select area of an index file returned by vxUseNtx or
  514. vxAreaNtx.
  515.  
  516. Returns:
  517.    TRUE if the index is a subindex or FALSE if it is not.
  518.  
  519. Usage:
  520.    It may be necessary to determine an update strategy or perhaps
  521. do something based upon the record count depending on whether or not the
  522. entire file is represented in the index. 
  523.  
  524. Example:
  525.    If vxIsSubNtx(vxNtxCurrent()) Then
  526.       NumRecs& = vxNumRecsSub()
  527.    Else
  528.       NumRecs& = vxNumRecs()
  529.    End If
  530.    
  531. See Also:
  532.    vxCreateSubNtx, vxNtxCurrent, vxNtxSubExpr, vxNumRecsSub, vxUseNtx
  533.  
  534.  
  535. vxLockRetry
  536. -----------
  537. Declaration:
  538.    Declare Sub vxLockRetry Lib "vxbase.dll" (ByVal ErrorMode As Integer,
  539. ByVal WaitSeconds As Integer)
  540.  
  541. Purpose:
  542.    Set the method of reporting a locked file or record to the user and
  543. also specify a lock try timeout value.
  544.  
  545. Parameters:
  546.    ErrorMode is passed as either TRUE or FALSE.
  547.  
  548.    If TRUE (the default), and an operation is performed that requires
  549. a lock (either record or file) which is unable to be set because another
  550. user has control of the record or file, the user is presented with a message
  551. from vxBase that asks if he wishes to retry the operation or abort.  If 
  552. "Retry" is chosen, vxBase attempts to set the lock again.  
  553.  
  554.    If ErrorMode is passed as FALSE, vxBase issues error code 610 "File lock
  555. error" instead of the retry message IF vxSetErrorMethod is set to TRUE. If the
  556. alternate error method is TRUE, the programmer can then set up his own
  557. method of dealing with locks through the VB ON ERROR routine.  
  558.  
  559.    If vxSetErrorMethod is FALSE and ErrorMode is FALSE, the default user retry
  560. message is sent instead.
  561.  
  562.    WaitSeconds is the number of seconds to continue to attempt setting a lock.
  563. If zero (0), and a lock fails, the lock function returns with the error
  564. immediately and either presents the "Retry" message to the user or triggers
  565. the vxBase 600 error depending on the value of ErrorMode and vxSetErrorMethod.
  566.  
  567.    If WaitSeconds is greater than zero, vxBase will continue to attempt to set
  568. the lock until WaitSeconds has expired. The maximum number of WaitSeconds that
  569. can be specified is 32,767 (which equates to over 9 hours) and is essentially
  570. a "wait forever" state.
  571.  
  572. Returns:
  573.    Nothing.
  574.  
  575. Usage:
  576.    In a multiuser environment the programmer often wishes to handle the failed
  577. lock scenario himself rather than rely on the user to retry the lock or not. This
  578. is the function of the errormode parameter.
  579.   
  580.    Setting WaitSeconds to about 20 is a good value for normal database operations.
  581. For example, if a record is to be written, vxBase will try over and over again
  582. for 20 seconds to set the lock. After the time has expired, the selected error
  583. method is executed.
  584.  
  585.    If using vxBase in an unattended program, it makes good sense to set the timeout
  586. value very high. Other processes that take control of a file for 15 or 20 minutes
  587. then do not necessarily disrupt the unattended program from performing its tasks
  588. after the file has been released.
  589.  
  590.    NOTE:  If a file is opened for exclusive use with vxUseDbfEX then ALL other
  591. processes requiring that file across the entire network will be denied access to
  592. the file.  The vxUseDbfEX function sets a network SHARE flag rather than a
  593. Clipper style lock on the file and no one is granted access to the file no matter
  594. what the value of vxSetLocks.
  595.  
  596.    NOTE:  vxLockRetry settings are GLOBAL to all vxBase tasks on a workstation.
  597. Once you select a set of values, you should use the same values in all of your vxBase
  598. programs.
  599.  
  600.  
  601. Example:
  602.    ' this function attempts to write a record and, if the required
  603.    ' lock fails, it send the user its own message asking for a
  604.    ' another attempt instead of using the vxBase default Retry? message
  605.    ' ------------------------------------------------------------------
  606.    Sub RecWrite
  607.       Dim vxError As vxErrorStruc
  608.       Dim RetryVal As Integer
  609.  
  610.       vxSetLocks FALSE
  611.       vxSetErrorMethod TRUE
  612.       vxLockRetry 0, 20
  613.       ' will use alternate error method after
  614.       ' retrying a lock for 20 seconds
  615.  
  616.       On Error GoTo LockError
  617.  
  618.       ' we will attempt to lock the record
  619.       ' as long as RetryVal is zero. If the
  620.       ' lock required by vxWrite fails, we
  621.       ' exit to the On Error routine - which
  622.       ' will set RetryVal to 2 if the user
  623.       ' does not wish to retry.
  624.       ' -------------------------------------
  625.       RetryVal = 0
  626.  
  627.       Do
  628.          If vxLockRecord() Then RetryVal = 1
  629.       Loop While RetryVal = 0
  630.  
  631.       If RetryVal = 1 Then 
  632.          If Not vxWrite() Then
  633.             MsgBox "Record Write Error"
  634.          End If      
  635.       End If
  636.       
  637.       vxSetErrorMethod FALSE
  638.       Exit Sub
  639.  
  640.    LockError:
  641.       If vxErrorTest(vxError) Then
  642.          If vxError.ErrorNum = 600 Then
  643.             j% = MsgBox("Lock failed. Retry?", 52)
  644.             If j% = 6 Then
  645.                Resume Next
  646.             Else
  647.                RetryVal = 2
  648.                Resume Next
  649.             End If
  650.          End If
  651.       End If
  652.  
  653.    End Sub
  654.  
  655. See Also:
  656.    vxIsRecLocked, vxLockDbf, vxLocked, vxLockRecord, vxSetLocks,
  657.    vxUnlock, vxUseDbfEX
  658.  
  659. vxMemCompact
  660. ------------
  661. Declaration:
  662.    Declare Function vxMemCompact Lib "vxbase.dll" () As Long
  663.  
  664. Purpose
  665.    Windows memory can become extremely fragmented when running a vxBase
  666. application. The vxBase program architecture is built of many small
  667. chunks which are all discardable and may be loaded on call. Other tasks
  668. running concurrently with vxBase can also contribute to memory
  669. fragmentation and consequent loss of perfromance or even out of memory
  670. conditions when a large request is made for some fixed memory (e.g.,
  671. reading a memo). vxMemCompact uses Windows API routines to compact
  672. memory and leave the largest contiguous free areas possible.
  673.  
  674. Parameters
  675.    None.
  676.  
  677. Returns
  678.    A long integer that contains the number of bytes in the largest free
  679. global memory object in the global heap.
  680.  
  681. Example
  682.    ' compact memory on each return to the controlling form
  683.    ' -----------------------------------------------------
  684.    Sub Form_Unload (Cancel As Integer)
  685.       vxWindowDereg(VXFORM5.hWnd)
  686.       vxMemCompact
  687.    End Sub
  688.  
  689.  
  690. vxMemoClear
  691. -----------
  692. Declaration:
  693.    Declare Function vxMemoClear Lib "vxbase.dll" (ByVal MemoFieldName
  694. As String) As Integer
  695.  
  696. Purpose:
  697.    Remove a memo block reference from a memo field. The bitmap OR memo
  698. attached to the field is effectively deleted.
  699.  
  700. Parameters:
  701.    MemoFieldName is either a string variable or a literal string that
  702. contains a valid memo field name from the currently selected database.
  703. MemoFieldName may be qualified with a valid alias name that points to
  704. any open database.
  705.  
  706. Returns:
  707.    TRUE if the operation was successful and FALSE if not. Always
  708. returns FALSE is always returned if the associated dbf has been opened
  709. as Read Only with vxUseDbfRO.
  710.  
  711. Usage:
  712.    Delete a memo or bitmap.
  713.  
  714. Example:
  715.  
  716.    Sub ButtonDelete_Click ()
  717.       If vxMemoClear("pic") Then
  718.          PicBox.Picture = LoadPicture()
  719.       Else
  720.          MsgBox "Delete failed"
  721.       End If
  722.  
  723. See Also:
  724.       vxIsMemo, vxIsPicture, vxReplMemo, vxPictureImport, vxSetAlias
  725.  
  726.  
  727. vxMemoPos
  728. ---------
  729. Declaration:
  730.    Declare Sub vxMemoPos Lib "vxbase.dll" (ByVal StartX As Integer,
  731. ByVal StartY As Integer, ByVal xWidth As Integer, ByVal yHeight As Integer,
  732. ByVal MemoTitle As String)
  733.  
  734. Purpose:
  735.    Set the start position and size of an upcoming memo edit window that
  736. will edit a memo attached to the current database with vxMemoEdit. Also
  737. used to set up the memo edit window title.
  738.  
  739. Parameters:
  740.    Window coordinates passed to this function use familiar character units
  741. in the x dimension and line height units in the y dimension. The units are
  742. converted to the average character width and height of the standard
  743. Windows system font and are therefore device independent.
  744.  
  745.    StartX is the start position of the memo window in characters from the
  746. left edge of the screen.
  747.  
  748.    StartY is the start position of the memo window in lines from the top
  749. of the screen.
  750.  
  751.    xWidth is the start width of the memo window in characters.
  752.  
  753.    yHeight is the height of the memo window (including caption and menu
  754. bars) in lines.
  755.  
  756. Returns:
  757.    Nothing.
  758.  
  759. Usage:
  760.    Memo window position and size are defaulted according to the size of
  761. the parent window passed to the vxMemoEdit function if this command is
  762. not issued. If this Sub is called, the position and size are relative to the
  763. entire screen.
  764.  
  765.    The default memo window caption is "Memo Edit: DBF name". If this is good
  766. enough, pass the MemoTitle as a null value (ByVal 0&).
  767.  
  768.    If you wish to set the memo title only and leave the size and position as
  769. the default values, pass all x and y coordinates as 0. For example,
  770. Call vxMemoPos(0,0,0,0,"My Memo Title")
  771.  
  772.    If the user sizes the memo window according to his own tastes, its position
  773. and size will be retained on subsequent edits.
  774.  
  775. Example:
  776.    Call vxMemoPos(10, 5, 60, 15, "Customer Complaints")
  777.    RecNum& = vxRecNo()
  778.    Call vxMemoEdit(VXFORM3.hWnd, "a_memo")
  779.    j% = vxGo(RecNum&)
  780.    j% = vxUnLock()
  781.  
  782. See Also:
  783.    vxMemoEdit
  784.  
  785.  
  786. vxMemRealloc
  787. ------------
  788. Declaration
  789.    Declare Function vxMemRealloc Lib "vxbase.dll" (ByVal NumDbf As Integer,
  790. ByVal NumNtx As Integer, ByVal ReindexBuff As Integer) As Integer
  791.  
  792. Purpose
  793.    Decrease the initial vxBase memory requirements.
  794.  
  795. Parameters
  796.    NumDbf is the number of dbf files that will be opened simultaneously. The
  797. minimum number is 2.
  798.  
  799.    NumNtx is the number of ntx files that will be opened simultaneously. The
  800. minimum number is 2.
  801.  
  802.    ReindexBuff is passed as either TRUE or FALSE. If TRUE, a 64k buffer used
  803. to speed up creation of indexes and the reindex/pack routines is set up. If
  804. this parameter is passed as FALSE, the buffer is either removed (if is has 
  805. already been created) or not set up at all.
  806.  
  807. Returns
  808.    TRUE if the memory reallocation was successful and FALSE if not. 
  809.  
  810. Usage
  811.    The first call to vxBase allocates about 160,000 bytes to track open dbf
  812. files and open index files and also creates a 64k buffer used by vxReindex,
  813. vxPack, and vxCreateNtx. By calling vxMemRealloc(2, 2, FALSE) this huge block
  814. of memory may be reduced to about 35,000 bytes. If you are not going to 
  815. be creating indexes, reindexing, or packing, the ReindexBuff may be passed
  816. as FALSE to remove an immediate 64k.
  817.  
  818.    You should not use this function to INCREASE memory requirements. Let
  819. vxBase handle that automatically. DBF descriptor blocks and NTX buffers
  820. are each limited to 64k (FAR pointer arithmetic is used by vxBase) so the
  821. maximum number of open dbf and ntx files for ALL concurrent vxBase tasks is
  822. about 75. If more memory is required by vxBase, it will increase the size of
  823. each dbf or ntx object by the immediate amount required (to a maximum of
  824. 64k each).
  825.  
  826.    This function should be called in your initialization routine. It should
  827. only be called ONCE. It is not designed as an all purpose vxBase memory
  828. manager; rather it is designed to let users with low memory situations
  829. customize specific vxBase applications.
  830.  
  831.    WARNING: Use this function with care. This function CLOSES all open dbf
  832. and ntx files that belong to the current task before the memory is
  833. reallocated. If any files are open that belong to OTHER vxBase tasks,
  834. the function fails. ALWAYS test the result for a TRUE value to ensure
  835. the reallocation takes place.
  836.  
  837.  
  838.  
  839. Example
  840.  
  841.    ' The FIRST form load is used to initalize vxbase  
  842.    ' -----------------------------------------------
  843.    Sub Form_Load ()
  844.       vxInit
  845.       vxCtlGraySet
  846.       vxSetLocks FALSE
  847.       j% = vxCloseAll()
  848.       If Not vxMemRealloc(2, 2, FALSE) Then
  849.          MsgBox "Reallocation failed"
  850.          End
  851.       End If
  852.    End Sub
  853.  
  854. See Also
  855.    vxInit, vxMemCompact
  856.  
  857.  
  858.  
  859. vxNtxSubExpr
  860. ------------
  861. Declaration:
  862.    Declare Function vxNtxSubExpr Lib "vxbase.dll" (ByVal NtxArea As Integer)
  863. As String
  864.  
  865. Purpose:
  866.    Extract the conditional expression that controls the insertion/deletion
  867. of keys in a subindex.
  868.  
  869. Parameters:
  870.    NtxArea is the select area of an index file returned by vxUseNtx or
  871. vxAreaNtx.
  872.  
  873. Returns:
  874.    A string that contains the conditional expression used to create the
  875. subindex. The string is either in Visual Basic format or C format depending
  876. upon the value of vxSetString.
  877.  
  878. Usage:
  879.    Especially useful in creating files at run time that are copies of
  880. existing files and that are to be indexed in the same way. Or in reporting
  881. the conditions of index insertion to the user.
  882.  
  883. Example:
  884.    If vxIsSubNtx(vxNtxCurrent()) Then
  885.       NumRecs& = vxNumRecsSub()
  886.       Form1.Caption = "Subindex on " + vxNtxExpr(vxNtxCurrent()) +
  887. " For Condition " + vxNtxSubExpr(vxNtxCurrent())
  888.    Else
  889.       NumRecs& = vxNumRecs()
  890.       Form1.Caption = "Master Index on " + vxNtxExpr(vxNtxCurrent())
  891.    End If
  892.    
  893. See Also:
  894.    vxCreateSubNtx, vxIsSubNtx, vxNtxCurrent, vxNtxExpr, vxNtxSubExpr,
  895.  vxNumRecsSub
  896.  
  897.  
  898. vxNumRecsFilter
  899. ---------------
  900. Declaration:
  901.    Declare Function vxNumRecsFilter Lib "vxbase.dll" () As Long
  902.  
  903. Purpose:
  904.    Return the number of records in the database that pass the defined
  905. filter.
  906.  
  907. Parameters:
  908.    None. The number of records returned is for the currently 
  909. selected database.
  910.  
  911. Usage:
  912.    Useful for generating accurate scroll bar extents and as a FOR LOOP
  913. counter. Note that this function does exactly what you would do to
  914. determine the number of records in a database that satisfy some
  915. condition. It must read every record in the database, evaluate the
  916. filter, and increment a counter. It is done at a lower level but
  917. still can take a lot of time in a large database.
  918.  
  919. Example:
  920.    j% = vxSelectDbf(TestDbf")
  921.    Debug.Print vxNumRecs()
  922.    Call vxFilter("trim(vxcountry)='CANADA')
  923.    Debug.Print vxNumrecsFilter()
  924.  
  925. See Also:
  926.    vxFilter, vxFilterReset, vxNumRecs, vxNumrecsSub
  927.  
  928. vxNumRecsSub
  929. ------------
  930. Declaration:
  931.    Declare Function vxNumRecsSub Lib "vxbase.dll" () As Long
  932.  
  933. Purpose:
  934.    Return the number of records in a subindex.
  935.  
  936. Parameters:
  937.    None. The subindex MUST be the currently selected index.
  938.  
  939. Usage:
  940.    Generally used as a FOR LOOP counter or as a statistic. It may also
  941. be used to set an accurate vertical scroll bar extent.
  942.  
  943. Example:
  944.    If vxIsSubNtx(vxNtxCurrent()) Then
  945.       NumRecs& = vxNumRecsSub()
  946.       Form1.Caption = "Subindex on " + vxNtxExpr(vxNtxCurrent()) +
  947. " For Condition " + vxNtxSubExpr(vxNtxCurrent())
  948.    Else
  949.       NumRecs& = vxNumRecs()
  950.       Form1.Caption = "Master Index on " + vxNtxExpr(vxNtxCurrent())
  951.    End If
  952.    
  953. See Also:
  954.    vxCreateSubNtx, vxIsSubNtx, vxNtxCurrent, vxNtxExpr, vxNtxSubExpr
  955.  
  956.  
  957. vxPictureImport
  958. ---------------
  959. Declaration:
  960.    Declare Function vxPictureImport Lib "vxbase.dll" (ByVal BmpFileName As
  961. String, ByVal MemoFieldName As String) As Integer
  962.  
  963. Purpose:
  964.    Import a bitmap from a system .BMP file into a memo field. The image
  965. may be displayed with vxPictureRead. The maximum size of the bitmap is
  966. 16 megabytes.
  967.  
  968. Parameters:
  969.    BmpFileName is the complete name of the bitmap file including path
  970. and extension. Files other than bitmaps may be stored into the memo
  971. file but they may not be read with vxPictureRead (unless they are run
  972. length encoded compressed variants of BMPS - i.e., RLE files in either
  973. 4 or 8 bit per pixel format). The file name may be represented by a
  974. literal string or a string variable.
  975.  
  976.    MemoFieldName is either a string variable or a literal string that
  977. contains a valid memo field name from the currently selected database.
  978. MemoFieldName may be qualified with a valid alias name that points to
  979. any open database.
  980.  
  981. Returns:
  982.    FALSE if the function fails and TRUE if successful. FALSE is always
  983. returned if the associated dbf has been opened as Read Only with
  984. vxUseDbfRO.
  985.  
  986. Usage:
  987.    It is much more efficient both from a retrieval standpoint and from
  988. a disk management standpoint to store bitmaps you wish to have 
  989. associated with database records in a single source file.
  990.    Store pictures of people in personnel files, parts images in
  991. inventory files, homes in real estate files, etc. 
  992.  
  993.    Files other than BMPs may also be stored in a memo file. Note, however,
  994. that only BMP or RLE format files are converted by vxPictureRead for display
  995. in a Visual basic picture box. The memo link parameters included in the
  996. vxCtlBrowse function will also result in bitmap display WITHOUT any
  997. effort required by the programmer other that defining the memo window
  998. and memo field name to the vxCtlBrowse function.
  999.  
  1000. Collecting Bitmaps
  1001.    vxBase takes advantage of the rich body of functions included in Visual
  1002. Basic to handle bitmap files. Bitmaps are the Windows norm; all paint
  1003. programs, viewers, etc. can handle bitmaps - and most programs that
  1004. deal with pictures can convert foreign formats (e.g., GIF) to BMPs.
  1005. As a last resort, cut a picture into the clipboard and paste it into a 
  1006. Windows PAINT window. It can then be stored as a .BMP file. 
  1007.  
  1008.    Once an image is stored in a BMP file it can be transferred to the 
  1009. memo file with the vxPictureImport function. To retrieve the bitmap,
  1010. vxBase uses the standard Windows Clipboard. It puts the bitmap out to
  1011. the clipboard as a DIB (device independent bitmap). The Visual Basic
  1012. Clipboard.GetData(8) function then is used to retrieve the image
  1013. from the clipboard and display it in a VB Picture Box. The box
  1014. can have the AUTORESIZE property set to TRUE as in the sample
  1015. application if the images are all different sizes
  1016.  
  1017.    Bitmap files can be created from existing images you may be using in
  1018. a Visual Basic program by calling the SavePicture function. You can then
  1019. call vxPictureImport to store the image in a memo file by using the name
  1020. of the bitmap file you created with SavePicture. You can also SavePicture
  1021. to export pictures from a memo file by first reading them into a picture
  1022. box with vxPictureRead.
  1023.  
  1024. Example:
  1025.    ' the name of the bmp picture file is the
  1026.    ' same as the string in field "title" so
  1027.    ' we can import the bmps into the memo file
  1028.    ' by cocatenating ".bmp" to the trimmed field
  1029.    ' contents
  1030.    ' -------------------------------------------
  1031.    j% = vxTop()
  1032.    If Not vxIsPicture("pic") Then
  1033.       For i& = 1 To 13 ' there are 13 recs in the file
  1034.          j% = vxGo(i&)
  1035.          ftitle$ = vxFieldTrim("type")
  1036.          fname$ = "c:\magic\bmp\" + ftitle$ + ".bmp"
  1037.          If Not vxPictureImport(fname$, "pic") Then
  1038.             MsgBox "Import Failed"
  1039.          End If
  1040.       Next i&
  1041.       j% = vxClose() ' close ensures buffers flushed
  1042.       AirPicsDbf = vxUseDbf("\vb\vxbtest\airpics.dbf")
  1043.       j% = vxSelectDbf(AirPicsDbf)
  1044.    End If  
  1045.  
  1046. See Also:
  1047.    vxIsPicture, vxMemoClear, vxPictureRead
  1048.  
  1049.  
  1050. vxPictureRead
  1051. -------------
  1052. Declaration:
  1053.    Declare Function vxPictureRead Lib "vxbase.dll" (ByVal PicHwnd
  1054. As Integer, ByVal MemoFieldName As String) As Integer
  1055.  
  1056. Purpose:
  1057.    Display a bitmap in a defined window that was stored in a memo 
  1058. file with vxPictureImport.
  1059.  
  1060. Parameters:
  1061.    PicHwnd is the window handle of the window that will receive the
  1062. image. In Visual basic, use vxCtlHwnd to convert a control handle to
  1063. a window handle.
  1064.  
  1065.    MemoFieldName is either a string variable or a literal string that
  1066. contains a valid memo field name from the currently selected database.
  1067. MemoFieldName may be qualified with a valid alias name that points to
  1068. any open database.
  1069.  
  1070. Returns:
  1071.    TRUE if the operation was successful and FALSE is not.
  1072.  
  1073. Usage:
  1074.    Only BITMAPS that have been stored with vxPictureImport may be
  1075. extracted with vxPictureRead. vxPictureRead assumes the binary object
  1076. contained in the memo is a formatted bitmap which contains a Windows
  1077. BITMAPFILEHEADER followed by a BITMAPINFOHEADER followed by an array
  1078. of RGBQUAD structures. All of this information is then followed by the
  1079. bitmap data itself. vxPictureRead creates a DIB (device independent 
  1080. bitmap) out of the Windows data structures and passes the DIB to the
  1081. clipboard, where it can easily be extracted and placed into a Visual
  1082. Basic picture box (or onto a form) with the ClipBoard.GetData(8)
  1083. function.
  1084.    If the structure contained in the memo is not a formal bitmap,
  1085. who knows what result?
  1086.  
  1087.    If you wish to store Binary Large Objects (BLOBs) in the memo file
  1088. other than bitmaps, you must use the vxBlobWrite and vxBlobRead functions
  1089. to access the data. These functions use Windows Global memory handles
  1090. as parameters and are not easily available to the Visual Basic programmer.
  1091.  
  1092.    NOTE: The memo link parameters included in the vxCtlBrowse function
  1093. will also result in bitmap display WITHOUT any effort required by the
  1094. programmer other than defining the memo window and memo field name to
  1095. the vxCtlBrowse function. When vxCtlBrowse displays a bitmap, it auto-
  1096. matically sizes the memo link window to the size of the bitmap. The top left
  1097. corner of your memo window is anchored. If there is not enough room on the 
  1098. form to contain the entire bitmap, it is clipped on the right and/or the
  1099. bottom to the limits of the parent form.
  1100.  
  1101. Example:
  1102.    The following code is a complete reproduction of the code contained
  1103. in VYFORM2 in the vxbtest project sample application:
  1104.  
  1105.  
  1106. ' static switch set to TRUE in form
  1107. ' load procedure so we know when this
  1108. ' form is first loaded
  1109. Dim FirstTime As Integer
  1110.  
  1111. Sub BrowseBox_KeyDown (KeyCode As Integer, Shift As Integer)
  1112.    ' whenever a record is highlighted, this
  1113.    ' proc receives a middle button code
  1114.    ' from the ctlBrowse so we can dynamically
  1115.    ' display the picture in the memo field
  1116.    ' -------------------------------------------
  1117.    If KeyCode = 4 Then  ' middle button?
  1118.       j% = vxSelectDbf(AirPicsDbf)
  1119.       RecNum& = vxCtlBrowseMsg(vxCtlHwnd(BrowseBox), VXB_GETCURRENTREC, 0)
  1120.       j% = vxGo(RecNum&)
  1121.       VYFORM2.Caption = vxFieldTrim("Title")
  1122.       If vxPictureRead(vxCtlHwnd(PicBox), "pic") Then
  1123.          ' the "8" param below is CF_DIB
  1124.          PicBox.Picture = Clipboard.GetData(8)
  1125.          ' If you want to leave the picture in
  1126.          ' the clipboard, comment out line below
  1127.          Clipboard.Clear
  1128.       Else
  1129.          PicBox.Picture = LoadPicture() ' clears the picture area
  1130.       End If
  1131.    End If
  1132.  
  1133.    ' -----------------------------------------------------------------
  1134.    ' NOTE: the code above is an example of using vxPictureRead.
  1135.    '       In this case (displaying records in a vxCtlBrowse table),
  1136.    '       it would be much more efficient to define the memo window
  1137.    '       and the memo field name to the vxCtlBrowse function instead
  1138.    ' -----------------------------------------------------------------
  1139. End Sub
  1140.  
  1141. Sub BrowseBox_KeyPress (KeyAscii As Integer)
  1142.  
  1143.    ' NOTE: YOU MUST ALWAYS TRAP THE ENTER KEY
  1144.    '       AND CHANGE THE KEYASCII CODE TO
  1145.    '       A ZERO WHEN USING VXCTLBROWSE
  1146.    '       EVEN IF YOU DON'T USE IT
  1147.    ' ----------------------------------------
  1148.    If KeyAscii = 13 Then
  1149.       KeyAscii = 0
  1150.       Exit Sub
  1151.    End If
  1152.  
  1153.    ' if ESC key is received, then emulate
  1154.    ' exit button press
  1155.    ' ------------------------------------
  1156.    If KeyAscii = 27 Then
  1157.       KeyAscii = 0
  1158.       ButtonExit_Click
  1159.       Exit Sub
  1160.    End If
  1161.  
  1162. End Sub
  1163.  
  1164. Sub ButtonExit_Click ()
  1165.    Unload VYFORM2
  1166. End Sub
  1167.  
  1168. Sub Form_Load ()
  1169.    ' set FirstTime switch on for Paint
  1170.    ' ---------------------------------
  1171.    FirstTime = True
  1172.  
  1173.    ' register the default database as the master
  1174.    ' -------------------------------------------
  1175.    AirPicsDbf = vxUseDbf("\vb\vxbtest\airpics.dbf")
  1176.    j% = vxSelectDbf(AirPicsDbf)
  1177.    
  1178.    ' first time load pictures
  1179.    j% = vxTop()
  1180.  
  1181.    ' the name of the bmp picture file is the
  1182.    ' same as the string in field "title" so
  1183.    ' we can import the bmps into the memo file
  1184.    ' by cocatenating ".bmp" to the trimmed field
  1185.    ' contents
  1186.    ' -------------------------------------------
  1187.    If Not vxIsPicture("pic") Then
  1188.       For i& = 1 To 13
  1189.          j% = vxGo(i&)
  1190.          ftitle$ = vxFieldTrim("type")
  1191.          fname$ = "c:\magic\bmp\" + ftitle$ + ".bmp"
  1192.          If Not vxPictureImport(fname$, "pic") Then
  1193.             MsgBox "Import Failed"
  1194.          End If
  1195.       Next i&
  1196.       j% = vxClose()
  1197.       AirPicsDbf = vxUseDbf("\vb\vxbtest\airpics.dbf")
  1198.       j% = vxSelectDbf(AirPicsDbf)
  1199.    End If
  1200.    
  1201.    ' set up the browse
  1202.    ' -----------------
  1203.    Call vxTableDeclare(VX_RED, ByVal 0&, ByVal 0&, 0, 1, 1)
  1204.    Call vxTableField(1, "Type", "type", VX_FIELD)
  1205.  
  1206.    Call vxBrowseCase(VX_UPPER)
  1207.    Call vxBrowseSetup(0, 0, 0, 1, "Helv", 15, VX_SEMIBOLD, 0, 0, 0, 0)
  1208.    ' If the typeface is too large on your display,
  1209.    ' CHANGE the parameter following "Helv" above to
  1210.    ' a smaller number
  1211.    ' ----------------------------------------------
  1212.    
  1213.    ' change the mouse pointer in the browse box
  1214.    ' from an I-Beam to an arrow to stop any flicker
  1215.    ' ----------------------------------------------
  1216.    BrowseBox.MousePointer = 1
  1217.  
  1218. End Sub
  1219.  
  1220. Sub Form_Paint ()
  1221.   ' register the database with this window
  1222.    ' --------------------------------------
  1223.    j% = vxSelectDbf(AirPicsDbf)
  1224.  
  1225.    ' make the form 3-d
  1226.    ' -----------------
  1227.    Call vxFormFrame(VYFORM2.hWnd)
  1228.    Call vxCtlStyle(BrowseBox, VX_RECESS)
  1229.  
  1230.    ' initiate the browse the first time only
  1231.    ' ---------------------------------------
  1232.    If FirstTime = True Then
  1233.       j% = vxCtlBrowse(vxCtlHwnd(BrowseBox), AirPicsDbf, 0, 0, 0, 0, " ")
  1234.       FirstTime = False
  1235.    End If
  1236.  
  1237.    ' on initial paint of the browse, middle button
  1238.    ' keydown is not sent to browse box so we want
  1239.    ' to do our dynamic display here as well as
  1240.    ' from a keydown in the browse box code
  1241.    ' ---------------------------------------------
  1242.    Call BrowseBox_KeyDown(4, 0)
  1243.   
  1244. End Sub
  1245.  
  1246. Sub Form_Resize ()
  1247.    VYFORM2.Refresh
  1248. End Sub
  1249.  
  1250. Sub Form_Unload (Cancel As Integer)
  1251.  ' close the browse
  1252.    ' ----------------
  1253.    k& = vxCtlBrowseMsg(vxCtlHwnd(BrowseBox), VXB_CLOSE, 0)
  1254.  
  1255.    ' close all the files
  1256.    ' -------------------
  1257.    j% = vxCloseAll()
  1258.  
  1259.    ' deregister the window and release memory
  1260.    ' ----------------------------------------
  1261.    vxWindowDereg (VYFORM2.hWnd)
  1262.  
  1263. End Sub
  1264.  
  1265. See Also:
  1266.    vxIsPicture, vxPictureImport
  1267.  
  1268.  
  1269. vxSetSelect
  1270. -----------
  1271. Declaration
  1272.    Declare Sub vxSetSelect Lib "vxbase.dll" (ByVal OnOrOff As Integer)
  1273.  
  1274. Purpose
  1275.    Turn off vxBase automatic database selection. Whenever a vxBase
  1276. database function is called, the last database selected for the current
  1277. window is used to perform the database function. If there was no
  1278. database active for the current window, then the last selected database
  1279. for the current task is automatically selected instead.
  1280.  
  1281. Parameters
  1282.    If OnOrOff is TRUE (the default), automatic database selection
  1283. according to the active window takes place whenever a vxBase function
  1284. that accesses a database is called. If FALSE, the last selection is used
  1285. without regard to window or task.
  1286.  
  1287. Returns
  1288.    Nothing.
  1289.  
  1290. Usage
  1291.    Used within Visual Basic sub functions where code attached to a
  1292. particular form does not come into play. Turning the auto select off
  1293. ensures there will be no incorrect selection going on that the
  1294. programmer is not aware of. Care must be taken when using this function
  1295. because, if the programmer allows the user to open a number of windows
  1296. each accessing a different database, the selection process may become
  1297. totally unhinged.
  1298.  
  1299.    vxSetSelect(FALSE) is normally used by C programmers writing DLLs or
  1300. VBXs which use vxBase calls. In a DLL, there is commonly no window that
  1301. can act as controller and even if there were, the programmer knows
  1302. exactly what database he is using and can reselect at every opportunity
  1303. to ensure the correct data comes into play.
  1304.  
  1305. Example
  1306.    ' sub function that does not interfere
  1307.    ' with auto selection of database in
  1308.    ' main line
  1309.    ' ------------------------------------
  1310.    Sub GetMasterNum()
  1311.       Call vxSetSelect(FALSE)
  1312.       PrevDbf% = vxSelectDbf(MasterDbf)
  1313.       MasterNum = vxInteger("masternum")
  1314.       Call vxSetSelect(TRUE)
  1315.       j% = vxSelectDbf(PrevDbf%)
  1316.    End Sub
  1317.  
  1318. See Also
  1319.    vxSelectDbf
  1320.  
  1321.  
  1322. vxUseDbfAgain
  1323. -------------
  1324. Declaration:
  1325.    Declare Function vxUseDbfAgain lib "vxbase.dll" (ByVal DbfName
  1326. As String) As Integer
  1327.  
  1328. Purpose:
  1329.    Opens a database that has already been opened IN ANOTHER AREA.
  1330. Any indexes attached to this database with vxUseNtx are also opened
  1331. in areas separate from any other instances of the same files.
  1332.  
  1333. See Also:
  1334.    vxUseDbf
  1335.  
  1336.      
  1337. vxUseDbfEX
  1338. ----------
  1339.    Declare Function vxUseDbfEX lib "vxbase.dll" (ByVal DbfName
  1340. As String) As Integer
  1341.  
  1342. Purpose:
  1343.    Opens a database for EXCLUSIVE use. If any other user or
  1344. task is currently using the database, this function will
  1345. fail (zero is returned as the select area).
  1346.  
  1347. See Also:
  1348.    vxUseDbf
  1349.  
  1350.  
  1351. IMPORTANT NOTES TO EXISTING VXBASE USERS:
  1352. -----------------------------------------
  1353.    (1) If your application uses DESCENDing indexs and your current vxBase
  1354.        release is less than 2.08, these indexes MUST BE RECREATED after
  1355.        installing this release. The descending key algorithm has been
  1356.        changed to make vxBase descending keys compatible with CLIPPER
  1357.        descending keys.
  1358.  
  1359.        DO NOT USE DATAWORKS to recreate the indexes. It still uses the
  1360.        old algorithm. DataWorks is in the process of update.
  1361.        Use the vxReindex or vxCreateNtx functions to recreate the indexes.
  1362.   
  1363.    (2) See the VXLOAD.EXE discussion below.
  1364.  
  1365. Prerequisites
  1366. -------------
  1367.    vxBase is a dynamic link library of xBase functions that has been
  1368. customized for use with Microsoft Visual Basic. You must have 
  1369. Visual Basic in order to run the VB sample application. 
  1370.    If you are intending to use vxBase with another language (such as 
  1371. C), create the directory \VB before beginning installation of vxBase.
  1372.    The default installation directory is \VB, which is where
  1373. Visual Basic is normally set up. The directory that vxBase is
  1374. installed into MUST exist. If \VB does not exist, or if you wish
  1375. to install vxBase into another directory, ensure that it exists
  1376. prior to installation.
  1377.  
  1378. vxBase Installation
  1379. -------------------
  1380.    If INSTALL.EXE is resident on this diskette, use the
  1381.    program manager RUN command A:INSTALL to install
  1382.    vxBase. If changing the default directory from \VB,
  1383.    the directory being changed to MUST exist.
  1384.  
  1385.    A second sample application (project vxbtut) has been
  1386.    included starting with release 2.05 that shows you how
  1387.    to maintain a single database using vxCtlBrowse as the
  1388.    primary user interface to the database. It is installed
  1389.    in directory \vb\vxbtest along with the vxbtest project.
  1390.  
  1391.  
  1392. ZIP version
  1393. -----------
  1394.     vxBase is distributed on a single diskette or on bulletin boards
  1395. as two compressed .ZIP files. The first ZIP file is vxbdoc.zip, which
  1396. contains the documentation in a Windows Write file. This file is
  1397. essential to understanding and using vxBase. If it is missing, contact
  1398. the author at the address below.  The documentation is separated from
  1399. the rest of vxBase to allow potential users to preview it before
  1400. installing and actually using vxBase. This is especially helpful to
  1401. potential users who extract vxBase from a bulletin board. They can
  1402. evaluate the system from a documentation standpoint before committing to
  1403. downloading the larger system.
  1404.  
  1405.     Unzip vxbdoc.zip and view or print it. The manual is more than
  1406. 250 pages long. It was formatted for an Epson 24-pin printer using
  1407. standard Courier fonts. Printed manuals may be obtained for $20.00.
  1408. See the end of the documentation for ordering information.
  1409.  
  1410.     The second ZIP file (vxbase.zip) contains the sample source code
  1411. and Visual Basic project files, vxbase.txt which includes all of the Visual
  1412. Basic declarations for the routines in the vxBase DLL, the vxBase DLL
  1413. itself, and VXLOAD.EXE - a Visual Basic Design Mode Utility.
  1414.  
  1415.     If you are going to upload vxBase to a bulletin board, it must be
  1416. sent as it was received - in two ZIP files.
  1417.  
  1418.     When the system ZIP file is decompressed, it contains this readme.doc
  1419. file and 3 more ZIP files. These ZIP files are:
  1420.  
  1421.     vxbdll.zip    the vxBase DLL and vxload.exe
  1422.     vxbtest.zip    sample source code and vxbase.txt
  1423.         vxbezy.zip      single database sample app using vxCtlBrowse
  1424.                         (project vxbtut)
  1425.  
  1426.     To install vxBase, first make a subdirectory under your \vb
  1427. directory named \vb\vxbtest and copy the vxbtest.zip and vxbezy.zip files
  1428. there. Unzip them and delete the zip files from your hard disk. To run the
  1429. sample applications it is essential that these files be in directory \vb\vxbtest
  1430. because this path is hard-coded into the sample code. If you MUST put them
  1431. somewhere else, you'll have to modify the file names in the source code to
  1432. reflect your location.
  1433.  
  1434.     Unzip vxbdll.zip and place the resulting files (VXBASE.DLL and VXLOAD.EXE)
  1435. in your \windows directory.
  1436.  
  1437.     To run the sample program, see the Sample Application section in the
  1438. manual. Remember to run vxload.exe before starting Visual Basic. 
  1439.  
  1440.  
  1441. VISUAL BASIC 2.0 And the Sample Applications
  1442. --------------------------------------------
  1443.     Visual Basic 2.0 or better is REQUIRED to run the sample
  1444. applications.        
  1445.  
  1446.  
  1447. Better Memory Management in Design Mode with VXLOAD.EXE
  1448. -------------------------------------------------------
  1449. NOTE: vxload.exe included with vxbase is a utility that simply
  1450.       loads vxbase.dll and runs in an iconized state. It is
  1451.       highly recommended that you run this program immediately 
  1452.       PRIOR to calling up Visual Basic in Design Mode. vxload
  1453.       controls the vxbase memory. Any crashes when testing a vxbase
  1454.       program in design mode will not affect the vxbase memory pool
  1455.       at all if vxload is running. Copy vxload.exe to your \windows
  1456.       directory and set it up as a group item next to your VB icon. 
  1457.  
  1458.       It is also suggested that you add the following two lines of
  1459.       code to your initialization procedure (somewhere after the call
  1460.       to vxInit()):
  1461.  
  1462.       Call vxSetLocks(FALSE)
  1463.       j% = vxCloseAll()
  1464.  
  1465.       vxSetLocks is described in the namual.
  1466.  
  1467.       Adding these two lines to the init procedure will close any
  1468.       files that were left open as a result of a Design Mode VB
  1469.       error. vxSetLocks will ensure that any open files left over
  1470.       from a crashed VB run will not have any leftover locks on
  1471.       your second and subsequent runs of the program while in Design
  1472.       Mode - and vxCloseAll will close any leftover files so you can
  1473.       start off with a clean slate.
  1474.  
  1475.       If you wish to use the default locking scheme in your finished
  1476.       .EXE, remove the vxSetLocks(FALSE) that you set up for design mode
  1477.       testing before compiling (and the vxCloseAll as well although
  1478.       that is not critical).
  1479.  
  1480.       If your vxBase program terminates abnormally (or you use the VB End
  1481.       menu item to terminate), and then you exit Visual Basic, an 
  1482.       attempt to close VXLOAD.EXE from the system menu that appears
  1483.       when you click on its icon will result in a "Task Sequence Closure
  1484.       Error". This is because your vxBase Visual Basic program never
  1485.       called vxDeallocate, which removes Visual Basic from the vxBase 
  1486.       task list being maintained by VXLOAD. If this happens to you,
  1487.       simply double click the VXLOAD icon to bring the VXLOAD window
  1488.       into view and select the EXIT menu item. Closing VXLOAD in this
  1489.       fashion ignores the task list.
  1490.  
  1491. Changes to vxBase version 2.xx
  1492. ------------------------------
  1493.   (1) vxBrowseSetup corrected to display user menus if system menus
  1494.       disabled.
  1495.  
  1496.   (2) vxCtlStyle corrected to handle new Visual Basic 2.0 "graphical
  1497.       objects" (e.g., labels).
  1498.  
  1499.   (3) all SETTINGS cited as System Wide in the current documentation are
  1500.       now local to the vxBase task. These settings include the following:
  1501.           vxCtlPenWidth
  1502.           vxSetAnsi
  1503.           vxSetCollate/vxCollate collating table
  1504.           vxSetDate
  1505.           vxSetErrorCaption
  1506.           vxSetErrorMethod
  1507.           vxSetLanguage
  1508.           vxSetLocks
  1509.           vxSetMeters
  1510.           vxSetString
  1511.  
  1512.        If more than one vxBase task is running at the same time, the
  1513.        items set by the functions above are now local to each concurrent
  1514.        task (e.g., vxBase in French and in English can be run on the same
  1515.        machine at the same time).
  1516.  
  1517.    (4) inconsistent index file lockup in multiuser mode when vxSeek
  1518.        fails corrected.
  1519.  
  1520.    (5) DESCEND and vxDescend index algorithms changed to use 2s complement
  1521.        instead of 1s complement arithmetic to convert defined descending
  1522.        keys into the correct sequence. This makes the vxBase DESCEND
  1523.        index compatible with CLIPPER.
  1524.  
  1525.    (9) memo soft returns from Clipper apps are now properly stripped on
  1526.        European memos when vxSetAnsi is FALSE.
  1527.  
  1528.   (10) vxBrowse and vxCtlBrowse quick key displays and vertical scrolling
  1529.        speeds have been increased by a factor of 2 to 3.
  1530.  
  1531.   (11) memory leaks created by VB 2.0 string creation corrected by using
  1532.        new function to create Visual Basic strings if version is 2.0 or
  1533.        greater.
  1534.  
  1535.   (12) Max memo size now increased to 64k (was 32k).
  1536.  
  1537.   (13) memo reading procedures changed to read 4k blocks instead of 64k file
  1538.        chunks. This should speed memo reads and packs with memo files
  1539.        considerably.
  1540.  
  1541.   (14) vxAppendFrom now appends memos and bitmaps. Restriction removed.
  1542.  
  1543.   (15) vxGo() passed with a zero record number now returns FALSE instead
  1544.        of crashing.
  1545.  
  1546.   (16) vxTop now properly returns FALSE if empty file.
  1547.  
  1548.   (17) dbf files opened as Read Only with vxUseDbfRO no longer have their
  1549.        index files locked when positioning to a specific record.
  1550.  
  1551.   (18) more elegant on screen edit within a vxBrowse or vxCtlBrowse table.
  1552.        The use may accept the edit by pressing the ENTER key or cancel the
  1553.        edit by pressing ESC.
  1554.  
  1555.   (19) initial memory allocation requirements reduced and memory increase
  1556.        requests changed to leave new memory object attached to original
  1557.        calling task.
  1558.  
  1559.   (20) Dutch language support added.
  1560.  
  1561.  
  1562.  
  1563. Terry Orletsky
  1564. vxBase Systems
  1565. #488, 9707 - 110 Street
  1566. Edmonton, Alberta, Canada
  1567. T5K 2L9
  1568. Phone (403) 488-8100
  1569. Fax   (403) 486-8150
  1570. BBS   (403) 488-8365 up to 14400 bps v.32bis 8N1
  1571. Compuserve I.D. 70524,3723
  1572. 
  1573.